package com.appfront;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.auxtools.CrashHandler;
import com.auxtools.LINE;
import com.rtuwrapper.messaging.ModbusException;
import com.rtuwrapper.messaging.ReadFloatRequest;
import com.rtuwrapper.messaging.ReadFloatResponse;
import com.rtuwrapper.messaging.ReadIntegerRequest;
import com.rtuwrapper.messaging.ReadIntegerResponse;
import com.rtuwrapper.messaging.ReadRegisterRequest;
import com.rtuwrapper.messaging.ReadRegisterResponse;

import java.util.ArrayList;
import java.util.List;

import lecho.lib.hellocharts.formatter.ColumnChartValueFormatter;
import lecho.lib.hellocharts.formatter.SimpleColumnChartValueFormatter;
import lecho.lib.hellocharts.gesture.ContainerScrollType;
import lecho.lib.hellocharts.gesture.ZoomType;
import lecho.lib.hellocharts.model.Axis;
import lecho.lib.hellocharts.model.AxisValue;
import lecho.lib.hellocharts.model.Column;
import lecho.lib.hellocharts.model.ColumnChartData;
import lecho.lib.hellocharts.model.Line;
import lecho.lib.hellocharts.model.LineChartData;
import lecho.lib.hellocharts.model.SubcolumnValue;
import lecho.lib.hellocharts.view.ColumnChartView;
import lecho.lib.hellocharts.view.LineChartView;

import static com.appfront.LoginActivity.transaction;

public class MainActivityDebug extends Activity {

    /* debug控件 */
    Button button_read;
    Button button_start;
    EditText text_main;
    EditText text_range;
    EditText text_unit;
    TextView logTextView;
    /* 双侧边栏控件 */
    LinearLayout layout_sampling;
    LinearLayout layout_uartSet;
    Button button_sampling_view;
    Button button_uartSet_view;
    boolean isSamplingViewShow = false;
    boolean isUartSetViewShow = false;
    Spinner spinner_uartName;
    EditText debug_nums;
    CheckBox debug_noMax;
    CheckBox debug_rawView;
    CheckBox debug_cubicView;
    Button debug_update;
    /* debug and main 共有控件 */
    TextView text_force;
    LineChartView chart_line;
    /* 读数据线程 */
    boolean isQuitNow = false;
    boolean isWaitingQuit = false;
    Thread read_thread;
    Mhandler mhandler;
    Errhandler ehandler;
    /* 绘图数据 */
    private List<Line>  chartLines = new ArrayList<Line>();
    private LineChartData lineChartData = new LineChartData();
    LINE forceLineRaw;
    LINE forceLineCubic;
    private ColumnChartData barData;
    /* 运动数据采集 */
    int now_freqs = 0;
    long group_startTime_ms = 0;
    /* 调试曲线参数 */
    boolean isStartedCharts = false;   // 调试用，开启/重启 串口读线程
    int freq_count;                     //计算采集频率
    long freq_count_lastTime_ms;       //辅助计算采集频率

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        CrashHandler.getInstance().init(this);

        setContentView(R.layout.activity_main_debug);
        chart_line = (LineChartView) findViewById(R.id.chart_line_debug);
        text_force = (TextView) findViewById(R.id.text_force_debug);
        button_read = (Button) findViewById(R.id.button_read);
        button_start = (Button) findViewById(R.id.button_start);
        text_main = (EditText) findViewById(R.id.editText_main);
        text_range = (EditText) findViewById(R.id.editText_range);
        text_unit = (EditText) findViewById(R.id.editText_unit);
        logTextView = (TextView) findViewById(R.id.logTextView_debug);
        layout_sampling = (LinearLayout) findViewById(R.id.debug_layout_sampling);
        layout_uartSet  = (LinearLayout) findViewById(R.id.debug_layout_uartSet);
        button_sampling_view = (Button) findViewById(R.id.button_debug_view);
        button_uartSet_view = (Button) findViewById(R.id.debug_uartSet);
        /* 串口配置UI控件 */
        spinner_uartName = (Spinner) findViewById(R.id.debug_spinner_uartName);
        /* sapmling 曲线UI控件 */
        debug_nums = (EditText) findViewById(R.id.debug_nums);
        debug_noMax = (CheckBox) findViewById(R.id.debug_noMax);
        debug_rawView = (CheckBox) findViewById(R.id.debug_rawView);
        debug_cubicView = (CheckBox) findViewById(R.id.debug_cubicView);
        debug_update = (Button) findViewById(R.id.debug_update);


        /* 串口设备spiner */
        List<String> strList_group = new ArrayList<String>();
        for(int i=0; i<4; i++)
            strList_group.add("/dev/ttyS" + i);
        ArrayAdapter<String> adapter_group = new ArrayAdapter<String>(this, R.layout.spinner_display_style, R.id.txtvwSpinner, strList_group);
        adapter_group.setDropDownViewResource(R.layout.spinner_dropdown_style);
        spinner_uartName.setAdapter(adapter_group);
        /* 初始化图表 */
        initLineChart();
        /* 更新拉力曲线参数 */
        debug_update.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int nums = Integer.parseInt(debug_nums.getText().toString());
                if(nums < 3)    nums = 3;
                TestproSetup.cubicNums = nums;
                TestproSetup.cubicNomax = debug_noMax.isChecked();
                if(debug_rawView.isChecked()){
                    if(!TestproSetup.isForceRawShow){
                        chartLines.add(forceLineRaw.line);
                        TestproSetup.isForceRawShow = true;
                    }
                }else{
                    if(TestproSetup.isForceRawShow){
                        chartLines.remove(forceLineRaw.line);
                        TestproSetup.isForceRawShow = false;
                    }
                    TestproSetup.isForceRawShow = false;
                }
                if(debug_cubicView.isChecked()){
                    if(!TestproSetup.isForceCubicShwo){
                        chartLines.add(forceLineCubic.line);
                        TestproSetup.isForceCubicShwo = true;
                    }
                }else{
                    if(TestproSetup.isForceCubicShwo){
                        chartLines.remove(forceLineCubic.line);
                        TestproSetup.isForceCubicShwo = false;
                    }
                }
            }
        });

        layout_sampling.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 0));
        layout_uartSet.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 0));
        button_sampling_view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                isSamplingViewShow = !isSamplingViewShow;
                if(isSamplingViewShow){
                    layout_sampling.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 3));
                }else{
                    layout_sampling.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 0));
                }
            }
        });
        button_uartSet_view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                isUartSetViewShow = !isUartSetViewShow;
                if(isUartSetViewShow){
                    layout_uartSet.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 3));
                }else{
                    layout_uartSet.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 0));
                }
            }
        });

        /* 读寄存器 */
        button_read.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                ReadIntegerRequest request = new ReadIntegerRequest();
                ReadIntegerResponse response;

                int readValue = 0;
                request.setData(0, readValue);
                try {
                    LoginActivity.transaction.execute(request);
                } catch (ModbusException e) {
                    toast("request err: " + e.toString());  //e.printStackTrace();
                }
                try {
                    response = (ReadIntegerResponse) LoginActivity.transaction.getResponse();
                    float realValue = response.getValue() - TestproSetup.forceBase;
                    log("reg = " + realValue);
                    text_force.setText("" + realValue + "N");

                } catch (ModbusException e) {
                    toast("response err: " + e.toString()); //e.printStackTrace();
                }
            }
        });

        button_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(false == isStartedCharts) {
                    if(read_thread.isAlive()){
                        isStartedCharts = true;
                        clearLineChart();
                    }else{
                        if(transaction != null) {
                            if (!read_thread.isAlive()) {
                                read_thread.setPriority(Thread.MAX_PRIORITY);
                                isStartedCharts = true;
                                clearLineChart();
                                read_thread.start();
                            }
                        }else{
                            toast("串口未连接");
                        }
                    }
                } else {
                    isStartedCharts = false;
                }
            }
        });

        mhandler = new Mhandler();
        ehandler = new Errhandler();
        read_thread = new Thread(new Runnable() {
            @Override
            public void run() {
                Message msg = mhandler.obtainMessage();
                Message errmsg = ehandler.obtainMessage();
                Bundle bundle = new Bundle();
                ReadIntegerRequest request = new ReadIntegerRequest();
                ReadIntegerResponse response;
                int err_count = 0;
                int readValue = 0;
                request.setData(0, readValue);
                while (true){
                    if(isQuitNow){
                        return;
                    }
                    if(false == isStartedCharts){
                        try {
                            Thread.sleep(200);
                        } catch (InterruptedException time_e) {
                            //e.printStackTrace();
                        }
                        continue;
                    } else {
                        try {
                            Thread.sleep(1);
                        } catch (InterruptedException time_e) {
                            //e.printStackTrace();
                        }
                    }

                    try {
                        transaction.execute(request);
                    } catch (ModbusException e) {
                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException time_e) {
                            //e.printStackTrace();
                        }
                        err_count++;
                        if(err_count > 100){
                            err_count = 0;
                            bundle.clear();
                            bundle.putString("err", "no response");
                            errmsg = ehandler.obtainMessage();
                            errmsg.setData(bundle);
                            ehandler.sendMessage(errmsg);
                        }
                        continue;
                    }
                    try {
                        response = (ReadIntegerResponse) transaction.getResponse();
                        readValue = response.getValue();
                    } catch (ModbusException e) {
                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException time_e) {
                            //e.printStackTrace();
                        }
                        bundle.clear();
                        bundle.putString("err", e.toString());
                        errmsg = ehandler.obtainMessage();
                        errmsg.setData(bundle);
                        ehandler.sendMessage(errmsg);
                        continue;
                    }
                    bundle = new Bundle();
                    bundle.putFloat("f", readValue - TestproSetup.forceBase);
                    msg = mhandler.obtainMessage();
                    msg.setData(bundle);
                    mhandler.sendMessage(msg);
                }
            }
        });
    }

    class Mhandler extends Handler {
        Bundle bundle;     //建立一个装数据用的箱子
        int refresh_count = 0;

        public Mhandler() { }
        public Mhandler(Looper L) {
            super(L);
        }

        @Override
        public void handleMessage(Message msg) {       //当有从另一线程传来的消息时 这里开始运行
            super.handleMessage(msg);
            bundle  = msg.getData();                    //msg是从另一线程传来的数据 ，先用箱子捕获数据
            float now_force = bundle.getFloat("f");                // Y值
            long now_time_ms = System.currentTimeMillis();          // X值

            /* 计算采集频率 */
            freq_count++;
            if(now_time_ms > freq_count_lastTime_ms+1000) {
                text_main.setText(Integer.toString(freq_count));
                freq_count = 0;
                freq_count_lastTime_ms = now_time_ms;
            }

            /* 计算 X & Y 坐标 */
            float xAxisValue = (float)((now_time_ms-group_startTime_ms)*0.001);
            forceLineRaw.add(xAxisValue, now_force);
            forceLineCubic.add(xAxisValue, forceLineRaw.getCublicValue(TestproSetup.cubicNums, TestproSetup.cubicNomax));

            // 刷新曲线图
            chart_line.setLineChartData(lineChartData);
            if(isWaitingQuit){
                if(Math.abs(now_force - LINE.trendBase) < 5){
                    isQuitNow = true;
                }
            }
            // 刷新右侧显示参数
            refresh_count++;
            if(refresh_count % 4 == 0){
                text_force.setText(String.format("%.1fN", now_force));

                if(now_freqs >= 10){
                    toast("测试完成");
                    isWaitingQuit = true;
                }
            }
        }
    }

    class Errhandler extends Handler {
        Bundle bundle;     //建立一个装数据用的箱子

        public Errhandler() { }
        public Errhandler(Looper L) {
            super(L);
        }

        @Override
        public void handleMessage(Message msg) {       //当有从另一线程传来的消息时 这里开始运行
            super.handleMessage(msg);
            bundle  = msg.getData();                    //msg是从另一线程传来的数据 ，先用箱子捕获数据
            String errstr = bundle.getString("err");
            toast(errstr);
        }
    }

    private void log(String text) {
        logTextView.setText(logTextView.getText().toString() + text + "\n");
    }
    private void toast(String text) {
        Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
    }

    private void initLineChart(){

        forceLineRaw = new LINE(chartLines, Color.parseColor("#00BFFF"));
        forceLineCubic = new LINE(chartLines, Color.BLUE);
        forceLineRaw.setMaxLineLen(400);
        forceLineCubic.setMaxLineLen(400);
        if(!TestproSetup.isForceRawShow)
            chartLines.remove(forceLineRaw.line);
        if(!TestproSetup.isForceCubicShwo)
            chartLines.remove(forceLineCubic.line);

        lineChartData.setLines(chartLines);
        //坐标轴
        Axis axisX = new Axis();            //X轴
        axisX.setHasTiltedLabels(true);     //X坐标轴字体是斜的显示还是直的，true是斜的显示
        //axisX.setTextColor(Color.BLUE);    //设置字体颜色
        //axisX.setName("date");            //表格名称
        axisX.setTextSize(10);              //设置字体大小
        axisX.setMaxLabelChars(8);          //最多几个X轴坐标，意思就是你的缩放让X轴上数据的个数7<=x<=mAxisXValues.length
        //axisX.setValues(mAxisXValues);      //填充X轴的坐标名称
        lineChartData.setAxisXBottom(axisX);         //x 轴在底部
        //data.setAxisXTop(axisX);          //x 轴在顶部
        axisX.setHasLines(true);            //x 轴分割线

        // Y轴是根据数据的大小自动设置Y轴上限(在下面我会给出固定Y轴数据个数的解决方案)
        Axis axisY = new Axis();            //Y轴
        axisY.setName("");                  //y轴标注
        axisY.setTextSize(10);              //设置字体大小
        lineChartData.setAxisYLeft(axisY);           //Y轴设置在左边

        //设置行为属性，支持缩放、滑动以及平移
        chart_line.setInteractive(true);
        chart_line.setZoomType(ZoomType.HORIZONTAL_AND_VERTICAL);
        chart_line.setMaxZoom((float) 4);//最大方法比例
        chart_line.setContainerScrollEnabled(true, ContainerScrollType.HORIZONTAL);
        chart_line.setLineChartData(lineChartData);

        chart_line.setVisibility(View.VISIBLE);
    }

    private void clearLineChart(){
        freq_count = 0;
        group_startTime_ms      = System.currentTimeMillis();
        freq_count_lastTime_ms  = group_startTime_ms;
        forceLineRaw.clear();
        forceLineCubic.clear();
        chart_line.setLineChartData(lineChartData);
    }

    @Override
    protected void onDestroy() {
        isQuitNow = true;
        if(read_thread != null){
            try {
                read_thread.join();
            } catch (InterruptedException e) {
                //e.printStackTrace();
            }
        }
        super.onDestroy();
    }
}